package com.logicfishsoftware.owlet.jena;

import com.hp.hpl.jena.rdf.model.Model;
import com.logicfishsoftware.owlet.app.ApplicationException;
import com.logicfishsoftware.owlet.app.Operator;
import com.logicfishsoftware.owlet.app.runtime.RuntimeApplication;
import com.logicfishsoftware.owlet.app.runtime.TransactionalRuntime;

/**
 * Hello world!
 *
 */
public abstract class JenaModelApp<T extends JenaModelApp<T,U>.JenaModelAtom,U extends JenaModelApp<T,U>.JenaModelContext>
extends TransactionalRuntime<T,U>
//implements Application<JenaModelOperator<U>>
{
	public class JenaModelContext 
	extends TransactionalRuntime<T, U>.TransactionalContext 
	{

		private T atomic;

		/**
		 * @param atomic
		 */
		protected JenaModelContext(T atomic) {
			this.atomic = atomic;
		}

		/* (non-Javadoc)
		 * @see com.logicfishsoftware.owlet.app.runtime.TransactionalRuntime.TransactionalContext#commit(com.logicfishsoftware.owlet.app.ApplicationRuntime.ApplicationAtom)
		 */
		@Override
		public void commit(T t) throws ApplicationException {
			if(atomic.supportsTransactions)
				atomic.getModel().commit();
		}

		/* (non-Javadoc)
		 * @see com.logicfishsoftware.owlet.app.runtime.TransactionalRuntime.TransactionalContext#rollback(com.logicfishsoftware.owlet.app.ApplicationRuntime.ApplicationAtom)
		 */
		@Override
		public void rollback(T t) throws ApplicationException {
			if(atomic.supportsTransactions)
				atomic.getModel().abort();
		}

		/* (non-Javadoc)
		 * @see com.logicfishsoftware.owlet.app.runtime.TransactionalRuntime.TransactionalContext#dispose()
		 */
		@Override
		public void dispose() throws ApplicationException {
			atomic.dispose();
		}		
		/**
		 * @return
		 * @throws ApplicationException 
		 */
		public Model getModel() throws ApplicationException {
			return atomic.getModel();
		}
		
	}
	public class JenaModelAtom 
	extends RuntimeApplication<T, U>.ApplicationAtom 
	{

		private JenaModelOperator<? super U> delegate;
		protected boolean supportsTransactions;

		/**
		 * @param delegate
		 * @throws ApplicationException 
		 */
		protected JenaModelAtom(JenaModelOperator<? super U> delegate) throws ApplicationException {
			this.delegate = delegate;
			this.supportsTransactions = getModel().supportsTransactions();
			if(supportsTransactions)
				getModel().begin();
		}

		/**
		 * @param proceed
		 * @throws ApplicationException 
		 */
		@SuppressWarnings("unchecked")
		protected JenaModelAtom(Operator<? super U> proceed) throws ApplicationException {
			this((JenaModelOperator<U>)proceed);
		}

		/**
		 * 
		 */
		public void dispose() {
			delegate.dispose();
		}
		
		/**
		 * @return the delegate
		 */
		protected JenaModelOperator<? super U> getDelegate() {
			return delegate;
		}

		/* (non-Javadoc)
		 * @see com.logicfishsoftware.owlet.app.ApplicationRuntime.ApplicationAtom#application(com.logicfishsoftware.owlet.app.ApplicationRuntime.ApplicationContext)
		 */
		@Override
		public boolean application(U context) throws Exception {
			return delegate.application(context);
		}

		/**
		 * @return
		 * @throws ApplicationException 
		 */
		public Model getModel() throws ApplicationException {
			return delegate.createModel();
		}

		/* (non-Javadoc)
		 * @see com.logicfishsoftware.owlet.app.ApplicationRuntime.ApplicationAtom#proceed()
		 */
		@Override
		public T proceed() throws ApplicationException {
			Operator<? super U> proceed = delegate.proceed();
			delegate = null;
			if(proceed!=null)
				return createAtom(proceed); //new JenaModelAtom(proceed);
			return null;
		}
		
	}
	
	/* (non-Javadoc)
	 * @see com.logicfishsoftware.owlet.app.Application#apply(java.lang.Object)
	 */
	public boolean apply(JenaModelOperator<U> delegate) throws ApplicationException {
		return enter(createAtom(delegate));
	}
	
//	@SuppressWarnings("unchecked")
//	protected T createAtom(Operator<? super U> proceed) throws ApplicationException {
//		return (T) new JenaModelAtom(proceed);
//	}	
	/* (non-Javadoc)
	 * @see com.logicfishsoftware.owlet.app.ApplicationRuntime#createFrame(com.logicfishsoftware.owlet.app.ApplicationRuntime.ApplicationAtom)
	 */
//	@SuppressWarnings("unchecked")
//	@Override
//	protected U createAppContext(T atomic) {
//		return (U) new JenaModelContext(atomic);
//	}
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}
